/**
 * 
 */
package za.co.sindi.oauth.core.context.web.portlet;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;

import javax.portlet.PortletContext;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PortletResponse;

import za.co.sindi.oauth.core.context.ApplicationContext;
import za.co.sindi.oauth.core.context.AttributeContext;
import za.co.sindi.oauth.core.context.RequestContext;
import za.co.sindi.oauth.core.context.ResponseContext;
import za.co.sindi.oauth.core.context.SessionContext;
import za.co.sindi.oauth.core.context.web.ResourceContext;

/**
 * @author Buhake Sindi
 * @since 25 March 2012
 *
 */
public class PortletApplicationContext implements ApplicationContext, ResourceContext, AttributeContext {

	private javax.portlet.PortletContext portletContext;
	private PortletRequest portletRequest;
	private PortletResponse portletResponse;

	/**
	 * @param portletContext
	 * @param portletRequest
	 * @param portletResponse
	 */
	public PortletApplicationContext(PortletContext portletContext, PortletRequest portletRequest, PortletResponse portletResponse) {
		super();
		if (portletContext == null) {
			throw new IllegalArgumentException("Portlet Context may not be null.");
		}
		
		if (portletRequest == null) {
			throw new IllegalArgumentException("Portlet Request may not be null.");
		}
		
		if (portletResponse == null) {
			throw new IllegalArgumentException("Portlet Response may not be null.");
		}
		
		this.portletContext = portletContext;
		this.portletRequest = portletRequest;
		this.portletResponse = portletResponse;
	}

	/**
	 * @return the portletContext
	 */
	public javax.portlet.PortletContext getPortletContext() {
		return portletContext;
	}

	/**
	 * @return the portletRequest
	 */
	public PortletRequest getPortletRequest() {
		return portletRequest;
	}

	/**
	 * @return the portletResponse
	 */
	public PortletResponse getPortletResponse() {
		return portletResponse;
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.AttributeContext#getAttribute(java.lang.String)
	 */
	@Override
	public Object getAttribute(String name) {
		// TODO Auto-generated method stub
		return getPortletContext().getAttribute(name);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.AttributeContext#getAttributeNames()
	 */
	@Override
	public String[] getAttributeNames() {
		// TODO Auto-generated method stub
		Enumeration<String> enums = getPortletContext().getAttributeNames();
		if (enums == null) {
			return null;
		}
		
		List<String> names = new ArrayList<String>();
		while (enums.hasMoreElements()) {
			names.add(enums.nextElement());
		}
		
		return names.toArray(new String[names.size()]);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.AttributeContext#removeAttribute(java.lang.String)
	 */
	@Override
	public void removeAttribute(String name) {
		// TODO Auto-generated method stub
		getPortletContext().removeAttribute(name);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.AttributeContext#setAttribute(java.lang.String, java.lang.Object)
	 */
	@Override
	public void setAttribute(String name, Object object) {
		// TODO Auto-generated method stub
		getPortletContext().setAttribute(name, object);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.web.ResourceContext#getRealPath(java.lang.String)
	 */
	@Override
	public String getRealPath(String path) {
		// TODO Auto-generated method stub
		return getPortletContext().getRealPath(path);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.web.ResourceContext#getResource(java.lang.String)
	 */
	@Override
	public URL getResource(String path) throws MalformedURLException {
		// TODO Auto-generated method stub
		return getPortletContext().getResource(path);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.web.ResourceContext#getResourceAsStream(java.lang.String)
	 */
	@Override
	public InputStream getResourceAsStream(String path) {
		// TODO Auto-generated method stub
		return getPortletContext().getResourceAsStream(path);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.web.ResourceContext#getResourcePaths(java.lang.String)
	 */
	@Override
	public Set<String> getResourcePaths(String path) {
		// TODO Auto-generated method stub
		return getPortletContext().getResourcePaths(path);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.ApplicationContext#getMimeType(java.lang.String)
	 */
	@Override
	public String getMimeType(String file) {
		// TODO Auto-generated method stub
		return getPortletContext().getMimeType(file);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.ApplicationContext#getServerInfo()
	 */
	@Override
	public String getServerInfo() {
		// TODO Auto-generated method stub
		return getPortletContext().getServerInfo();
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.ApplicationContext#log(java.lang.String)
	 */
	@Override
	public void log(String message) {
		// TODO Auto-generated method stub
		getPortletContext().log(message);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.ApplicationContext#log(java.lang.String, java.lang.Throwable)
	 */
	@Override
	public void log(String message, Throwable throwable) {
		// TODO Auto-generated method stub
		getPortletContext().log(message, throwable);
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.ApplicationContext#requestDispatch(java.lang.String)
	 */
	@Override
	public void requestDispatch(String path) throws IOException {
		// TODO Auto-generated method stub
		try {
			PortletRequestDispatcher dispatcher = getPortletContext().getRequestDispatcher(path);
			dispatcher.forward(getPortletRequest(), getPortletResponse());
		} catch (PortletException e) {
			// TODO Auto-generated catch block
			throw new IOException(e);
		}
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.ApplicationContext#getContext()
	 */
	@Override
	public Object getContext() {
		// TODO Auto-generated method stub
		return getPortletContext();
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.ApplicationContext#getRequestContext()
	 */
	@Override
	public RequestContext getRequestContext() {
		// TODO Auto-generated method stub
		return new PortletRequestContext(getPortletRequest());
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.ApplicationContext#getResponseContext()
	 */
	@Override
	public ResponseContext getResponseContext() {
		// TODO Auto-generated method stub
		return new PortletResponseContext(getPortletResponse());
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.ApplicationContext#getSessionContext()
	 */
	@Override
	public SessionContext getSessionContext() {
		// TODO Auto-generated method stub
		return new PortletSessionContext(getPortletRequest().getPortletSession());
	}

	/* (non-Javadoc)
	 * @see com.neurologic.oauth.core.context.ApplicationContext#getSessionContext(boolean)
	 */
	@Override
	public SessionContext getSessionContext(boolean create) {
		// TODO Auto-generated method stub
		return new PortletSessionContext(getPortletRequest().getPortletSession(create));
	}
}
